//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.tuiofx.internal.gesture;

import java.awt.*;
import java.util.HashMap;
import java.util.Map;

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.event.EventTarget;
import javafx.scene.Node;
import javafx.scene.input.TouchPoint;
import javafx.scene.input.TouchPoint.State;
import javafx.util.Duration;
import org.tuiofx.Configuration;
import org.tuiofx.internal.util.LogUtils;
import org.tuiofx.internal.util.Util;

public class TouchRecognizer extends GestureRecognizer {
    private Map<EventTarget, ClickCounter> counters = new HashMap<>();

    public TouchRecognizer(Node targetNode, Configuration config) {
        super(targetNode, config);
        this.requiredNumberOfTouches = 1;
    }

    public void touchesBegan(TuioTouchPoint touchPoint) {
        this.fireTouchEvent(touchPoint, State.PRESSED);
        ClickCounter counter = this.createClickCounter((Node) touchPoint.getTargetNode());
        counter.start(touchPoint.getSceneX(), touchPoint.getSceneY());
    }

    private ClickCounter createClickCounter(Node targetNode) {
        ClickCounter counter = this.counters.get(targetNode);
        if (counter == null) {
            counter = new ClickCounter();
            this.counters.put(targetNode, counter);
        }

        return counter;
    }

    public void touchesMove(TuioTouchPoint touchPoint) {
        ClickCounter counter = this.counters.get(touchPoint.getTargetNode());
        if (counter == null) {
            LogUtils.error("Counter Should not be null");
        } else {
            counter.moved(touchPoint.getSceneX(), touchPoint.getSceneY());
            TouchPoint.State touchState;
            if (counter.isStill()) {
                touchState = State.STATIONARY;
            } else {
                touchState = State.MOVED;
            }

            this.fireTouchEvent(touchPoint, touchState);
        }
    }

    public void touchesEnd(TuioTouchPoint touchPoint) {
        this.fireTouchEvent(touchPoint, State.RELEASED);
    }

    private static class ClickCounter {
        private int clickCount;
        Toolkit toolkit;
        private Timeline timeout;
        private boolean timeoutIsReached;
        private boolean still;
        private double pressedX;
        private double pressedY;

        private ClickCounter() {
            this.clickCount = 0;
            this.toolkit = Toolkit.getDefaultToolkit();
        }

        int incrementClickCount() {
            return this.clickCount++;
        }

        boolean isTimeoutReached() {
            return this.timeoutIsReached;
        }

        private boolean isStill() {
            return this.still;
        }

        int getClickCount() {
            return this.clickCount;
        }

        private void clear() {
            this.clickCount = 0;
        }

        private void out() {
            this.timeoutIsReached = true;
            this.stopTimeout();
        }

        private void moved(final double x, final double y) {
            Platform.runLater(new Runnable() {
                public void run() {
                    if (Math.abs(x - ClickCounter.this.pressedX) > 10.0 || Math.abs(y - ClickCounter.this.pressedY) > 10.0) {
                        ClickCounter.this.out();
                        ClickCounter.this.still = false;
                    }

                }
            });
        }

        private void start(double x, double y) {
            this.pressedX = x;
            this.pressedY = y;
            if (this.timeoutIsReached) {
                this.clear();
            }

            this.timeoutIsReached = false;
            ++this.clickCount;
            if (this.timeout != null) {
                this.timeout.stop();
            }

            Platform.runLater(new Runnable() {
                public void run() {
                    ClickCounter.this.timeout = new Timeline();
                    ClickCounter.this.timeout.getKeyFrames().add(new KeyFrame(new Duration(Util.getToolkitMultiClickInterval(ClickCounter.this.toolkit)), new EventHandler<ActionEvent>() {
                        public void handle(ActionEvent event) {
                            ClickCounter.this.timeoutIsReached = true;
                            ClickCounter.this.timeout = null;
                        }
                    }, new KeyValue[0]));
                    ClickCounter.this.timeout.play();
                }
            });
            this.still = true;
        }

        private void stopTimeout() {
            if (this.timeout != null) {
                this.timeout.stop();
            }

            this.timeout = null;
        }
    }
}
